package com.elitecrm.chatesop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class loginChatEsop extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static final Log log = LogFactory.getLog(loginChatEsop.class);

    private static final String classString = "loginChatEsop";
    private String apiURL;
    private String errorURL;
    private String visitorURL;

    public void destroy() {
        super.destroy();
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 调用类型校验,此接口仅支持GET
        String getMethod = request.getMethod();
        log.debug("getMethod:" + getMethod);
        if (!getMethod.equals("GET")) {
            log.error("HTTP请求调用类型错误，接口调用失败：" + getMethod);
            errorRedirect(response, "页面异常", "HTTP请求调用类型错误：" + getMethod);
        }

        // 获取所有Header
        Map<String, String> mapHeader = new HashMap<String, String>();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            log.debug("Call Header-" + key + ":" + value);

            mapHeader.put(key, value);
        }

        // 获取所有参数名
        Map<String, String> mapParams = new HashMap<String, String>();
        Enumeration ep = request.getParameterNames();
        while (ep.hasMoreElements()) {
            String key = (String) ep.nextElement();
            String value = request.getParameter(key);
            log.debug("Call Parameter-" + key + ":" + value);
            mapParams.put(key, value);

        }

        log.debug("原始Get请求参数 mapParams:" + mapParams.toString());

        String device = GetMapV(mapParams, "device");
        String state = GetMapV(mapParams, "state");
        String visitor = GetMapV(mapParams, "visitor");
        if (isNull(device)) {

            log.warn("必要参数不能为空：device/state");
            errorRedirect(response, "参数异常", "必要参数不能为空：device/state");
        } else {

            // 方法标记(如果是访客直接跳访客地址进线)
            if (visitor.equals("1")) {
                if (isNull(visitorURL)) {
                    errorRedirect(response, "访客地址异常", "系统维护中,暂时不支持访客进线...");
                } else {
                    // 拼接参数
                    mapParams.put("type", "0");
                    String queryStr = getQueryString(mapParams);
                    response.sendRedirect(visitorURL + "?" + queryStr);
                }

            } else {

                // 获取token
                CloseableHttpClient httpClient = HttpClientBuilder.create().build();
                CloseableHttpResponse callResp = null;
                log.debug("要转发的地址：" + apiURL);
                try {
                    // 拼接参数
                    mapParams.put("type", "1");
                    String queryStr = getQueryString(mapParams);

                    // 调用内部接口
                    callResp = httpClient.execute(new HttpGet(apiURL + "?" + queryStr));
                    HttpEntity entity = callResp.getEntity();
                    int status = callResp.getStatusLine().getStatusCode();
                    response.setStatus(status);
                    if (status == 200 && entity != null) {

                        // 获取响应头
                        Header[] headers = callResp.getAllHeaders();

                        // 获取接口返回
                        String result = EntityUtils.toString(entity, "UTF-8");

                        if (isNull(result) || !result.startsWith("http")) {
                            log.warn("接口返回重定向地址为空：" + result);
                            errorRedirect(response, "地址异常", "接口返回重定向地址错误：" + result);
                        } else {
                            response.sendRedirect(result);
                        }
                    } else {
                        errorRedirect(response, "登录处理异常", "登录处理异常错误:无重定向URL");
                    }
                } catch (Exception e) {
                    log.error("处理异常", e);
                } finally {
                    try {
                        if (httpClient != null) {
                            httpClient.close();
                        }
                        if (callResp != null) {
                            callResp.close();
                        }
                    } catch (IOException e) {
                        log.error("关闭流异常", e);
                    }
                }
            }
        }
    }

    public void init() throws ServletException {
        log.info("接口服务" + classString + " 初始化开始...");
        this.apiURL = getInitParameter("apiURL");
        this.errorURL = getInitParameter("errorURL");
        this.visitorURL = getInitParameter("visitorURL");
        log.info("接口服务" + classString + " 初始化完成... apiURL:" + apiURL + " errorURL:" + errorURL + " visitorURL:" + visitorURL);
    }

    // 异常&错误重定向
    public void errorRedirect(HttpServletResponse response, String ErrorTitle, String ErrorInfo) throws IOException {
        log.warn("异常&错误[apiDynLogin]重定向 ErrorTitle:" + ErrorTitle + " ErrorInfo:" + ErrorInfo);
        ErrorTitle = isNull(ErrorTitle) ? "页面异常" : ErrorTitle;
        ErrorInfo = isNull(ErrorInfo) ? "请稍后再试或联系管理员." : ErrorInfo;
        response.sendRedirect(this.errorURL + "/404.html?ErrorTitle=" + encode(ErrorTitle) + "&ErrorInfo=" + encode("登录异常&错误:" + ErrorInfo).replaceAll("\\+", "%20"));
    }

    // 工具方法
    public static String getQueryString(Map<String, String> params) {
        String url = "";
        if (params == null) {
            return url;
        }

        StringBuilder builder = new StringBuilder(url);

        int i = 0;
        for (String key : params.keySet()) {
            String value = params.get(key);
            if (value == null) { // 过滤空的key
                continue;
            }

            if (i != 0) {
                builder.append('&');
            }

            builder.append(key);
            builder.append('=');
            builder.append(encode(value));

            i++;
        }

        return builder.toString();
    }

    // 工具方法
    public static String encode(String input) {
        if (input == null) {
            return "";
        }

        try {
            return URLEncoder.encode(input, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return input;
    }

    // 解析Mapn值(此方法增加需要解析的key不存在保护)
    public static String GetMapV(Map inMap, String getKey) {
        String Rev_Value = null;
        try {
            Rev_Value = String.valueOf(inMap.get(getKey));
        } catch (Exception e) {

            Rev_Value = "";
        } finally {
            if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
                Rev_Value = "";
            }
        }
        return Rev_Value;
    }

    // 非空校验isNull
    public static boolean isNull(String value) {

        boolean reFlag = true;
        if (value == null || value.length() <= 0) {
            reFlag = true;
        } else {
            reFlag = false;
        }

        return reFlag;
    }
}